package com.purchase.ml.resource.sys;


import com.purchase.ml.annotations.OperLog;
import com.purchase.ml.bean.base.ApiRestResult;
import com.purchase.ml.bean.req.mail.MailDto;
import com.purchase.ml.bean.req.mail.RePwdDto;
import com.purchase.ml.bean.req.sys.*;
import com.purchase.ml.bean.res.sys.LoginUserResponse;
import com.purchase.ml.consts.Constants;
import com.purchase.ml.entity.acc.SysUser;
import com.purchase.ml.entity.log.OperationLog;
import com.purchase.ml.enums.ManagerStatusEnum;
import com.purchase.ml.enums.RetStatusNum;
import com.purchase.ml.exception.BizException;
import com.purchase.ml.exception.CommonEnum;
import com.purchase.ml.resource.BaseResource;
import com.purchase.ml.security.JwtUtil;
import com.purchase.ml.service.sys.ISysRoleUserService;
import com.purchase.ml.service.sys.SysUserService;
import com.purchase.ml.service.log.OperationLogService;
import com.purchase.ml.utils.HttpUtil;
import com.purchase.ml.utils.MD5;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Date;

/**
 * <p>
 * 用户账号
 * </p>
 *
 * @author kyyang
 * Created 2021-01-05
 */

@RestController
@RequestMapping("/sys")
@Slf4j
@Api(tags = "账户")
public class SysUserResource extends BaseResource {


    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private ISysRoleUserService iSysRoleUserService;

    @Autowired
    private OperationLogService operationLogService;

    @Value("${purchase.ml.version}")
    private String operVer;

    /**
     * @description: 用户登录
     * 登录时候无token 不能通过切点去用户信息
     * @author kyyang
     * @date 2021/1/6 19:18
     * @version 1.0
     */
    @RequestMapping(method = RequestMethod.POST, path = "/login")
    @ApiOperation("用户登录")
    public ApiRestResult login(@Valid @RequestBody SysLoginParam loginParam) {
        try {

            String userName = loginParam.getAcc();
            String password = loginParam.getPwd();

            SysUser user = sysUserService.findByAccount(userName);
            if (user == null){
                return ApiRestResult.err(RetStatusNum.ACC_NO.getMessage(), RetStatusNum.ACC_NO.getCode());
            }
            if (user.getState().equals(Constants.ABNORMAL_STATE)) {
                return ApiRestResult.err(RetStatusNum.ACC_FREEZE.getMessage(), RetStatusNum.ACC_FREEZE.getCode());
            }
            else if (user.getState().equals(Constants.DELETE_STATE)) {
                return ApiRestResult.err(RetStatusNum.ACC_DEL.getMessage(), RetStatusNum.ACC_DEL.getCode());
            }
            if (user == null) {
                return ApiRestResult.err(RetStatusNum.ACC_ERROR.getMessage(), RetStatusNum.ACC_ERROR.getCode());
            }
            String passwdMd5 = MD5.md5(password, user.getSalt());
            //2,
            if (!user.getPwd().equals(passwdMd5)) {
                return ApiRestResult.err(RetStatusNum.ACC_ERROR.getMessage(), RetStatusNum.ACC_ERROR.getCode());
            }
//            List<SysRoleUser> sysRoleUsers = iSysRoleUserService.listByUserId(user.getId());
//            if (sysRoleUsers == null || sysRoleUsers.size() < 1) {
//                return ApiRestResult.err(RetStatusNum.NO_PERMISSION.getMessage(), RetStatusNum.NO_PERMISSION.getCode());
//            }
            String token = sysUserService.loginForToken(user);
            LoginUserResponse loginUserResponse = new LoginUserResponse();
            loginUserResponse.setUserId(user.getId());
            loginUserResponse.setRoleType(user.getRoleType());
            loginUserResponse.setDealerId(user.getDealerId());
            loginUserResponse.setToken(token);

            //用户登录埋点
            OperationLog entiry = new OperationLog();
            entiry.setOperModule("sys");
            entiry.setOperDesc("userLogin");
            entiry.setOperIp(HttpUtil.getIp());
            entiry.setOperMethod("com.purchase.ml.resource.sys.SysUserResource.login");
            // entiry.setOperReqParam(JSON.toJSONString(loginParam));
            //entiry.setOperResParam(JSON.toJSONString(loginUserResponse));
            entiry.setOperUri("/purchase/sys/login");
            entiry.setOperType("login");
            entiry.setOperVer(operVer);
            entiry.setOperCreateTime(new Date());
            entiry.setOperUserId(user.getAcc());
            entiry.setOperUserName(user.getName());
            operationLogService.save(entiry);


            //记录登录时间
            SysUser u = new SysUser();
            u.setId(user.getId());
            u.setLastLoginAt(new Date());
            sysUserService.updateById(u);

            return ApiRestResult.ok(loginUserResponse);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return ApiRestResult.err("登录时失败");

    }


    @RequestMapping(method = RequestMethod.POST, path = "/new")
    @OperLog(operDesc = "AccountNew", operModul = "Account", operType = "New")
    @ApiOperation("账户创建")
    public ApiRestResult accountNew(@Valid @RequestBody SysUserDto accUserDto) {
        //检查该用户是否存在
        SysUser byAccount = sysUserService.findByAccount(accUserDto.getAcc());
        if (byAccount != null) {
            return ApiRestResult.err(RetStatusNum.ACC_REP.getMessage(), RetStatusNum.ACC_REP.getCode());
        }
        SysUser currentUser = getCurrentUser();
        if(ManagerStatusEnum.ADMIN.getCode().equals(currentUser.getIsAdmin())){
            if (accUserDto.getDealerId() != null){
                accUserDto.setDealerId(accUserDto.getDealerId());
            }else{
                accUserDto.setDealerId(666L);
            }
        }else{
            accUserDto.setIsAdmin(0);
        }

        sysUserService.save(accUserDto);
        return ApiRestResult.ok();
    }


    @RequestMapping(method = RequestMethod.POST, path = "/logout")
    @OperLog(operDesc = "注销登录", operModul = "sys", operType = "logout")
    @ApiOperation("注销登录")
    public ApiRestResult logout() {
        sysUserService.logout();
        return ApiRestResult.ok();
    }


    @RequestMapping(method = RequestMethod.POST, path = "/query")
    @ApiOperation("账户查询")
    public ApiRestResult accountQuery(@RequestBody SysUserQueryDto accUserQueryDto) {
        SysUser currentUser = getCurrentUser();
        if(ManagerStatusEnum.NO_ADMIN.getCode().equals(currentUser.getIsAdmin())){
            accUserQueryDto.setDealerId(currentUser.getDealerId());
        }
        return ApiRestResult.ok(sysUserService.selectAccByPage(accUserQueryDto));
    }

    @RequestMapping(method = RequestMethod.POST, path = "/edit/info")
    @OperLog(operDesc = "账户信息修改", operModul = "sys", operType = "edit")
    @ApiOperation("账户信息修改")
    public ApiRestResult editInfo(@Valid @RequestBody SysUserEditDto accUserEditDto) {
        SysUser byAccount = sysUserService.getById(accUserEditDto.getId().longValue());
        if (byAccount == null) {
            return ApiRestResult.err(RetStatusNum.ACC_NO.getMessage(), RetStatusNum.ACC_NO.getCode());
        }
        SysUser currentUser = getCurrentUser();
        if(ManagerStatusEnum.NO_ADMIN.getCode().equals(currentUser.getIsAdmin())){
            accUserEditDto.setMerchantId(currentUser.getDealerId());
        }
        sysUserService.editInfo(accUserEditDto);
        return ApiRestResult.ok();
    }

    @RequestMapping(method = RequestMethod.POST, path = "/edit/resetpwd")
    @OperLog(operDesc = "账号重置密码", operModul = "sys", operType = "edit")
    @ApiOperation("账户重置密码")
    public ApiRestResult editResetpwd(@Valid @RequestBody SysRepwdDto dto) {

        SysUser byAccount = sysUserService.getById(dto.getUserId());
        if (byAccount == null) {
            return ApiRestResult.err(RetStatusNum.ACC_NO.getMessage(), RetStatusNum.ACC_NO.getCode());
        }
        sysUserService.editResetpwd(byAccount);
        return ApiRestResult.ok();
    }

    @RequestMapping(method = RequestMethod.POST, path = "/edit/newpwd")
    @OperLog(operDesc = "账号修改密码", operModul = "sys", operType = "edit")
    @ApiOperation("账号修改密码")
    public ApiRestResult editPwd(@Valid @RequestBody SysUserEditPwdDto accUserEditPwdDto) {

        SysUser sysUser = sysUserService.getById(JwtUtil.getUserId());
        if (sysUser == null) {
            return ApiRestResult.err(RetStatusNum.ACC_NO.getMessage(), RetStatusNum.ACC_NO.getCode());
        }
        //校验旧密码是否正确
        String md5 = MD5.md5(accUserEditPwdDto.getOldpwd(), sysUser.getSalt());
        if(!sysUser.getPwd().equals(md5)){
            return ApiRestResult.err(RetStatusNum.ACC_OLD_PWD.getMessage(), RetStatusNum.ACC_OLD_PWD.getCode());
        }

        sysUserService.editPwd(sysUser,accUserEditPwdDto);
        return ApiRestResult.ok();
    }

    @PostMapping("/user/info")
    @ApiOperation("账户登录后，返回用户信息")
    public ApiRestResult userInfo(){
        Long userId = JwtUtil.getUserId();
        SysUser user = sysUserService.getById(userId);
        user.setPwd("******");
        return ApiRestResult.ok(user);
    }

    @RequestMapping(method = RequestMethod.POST, path = "/menu")
    @ApiOperation("当前账户菜单列表查询")
    public ApiRestResult accountMenuQuery() {
        return ApiRestResult.ok(sysUserService.accountMenuQuery());
    }

    @RequestMapping(method = RequestMethod.POST, path = "/permissions")
    @ApiOperation("当前账户页面权限查询")
    public ApiRestResult accountPermissionsQuery(@RequestBody SysPermissionsDto accPermissionsDto) {
        return ApiRestResult.ok(sysUserService.accountPermissionsQuery(accPermissionsDto));
    }

    @PostMapping("/forgetPwd")
    @ApiOperation("忘记密码，进行重置")
    public ApiRestResult forgetPwd(@Valid @RequestBody MailDto dto){
        Boolean isTrue = sysUserService.handleResetPwd(dto);
        if(!isTrue){
            return ApiRestResult.err(RetStatusNum.NOUSER_ERROR);
        }
        return ApiRestResult.ok();
    }

    @PostMapping("/mail/rePwd")
    @ApiOperation(value = "通过邮件验证码重置密码")
    public ApiRestResult rePwd(@RequestBody @Valid RePwdDto dto){
        SysUser user = sysUserService.findByAccount(dto.getEmail());
        if(user == null){
            return ApiRestResult.err(RetStatusNum.NOUSER_ERROR);
        }
        //验证重置码是否正确
        Boolean isTrue = sysUserService.verifyRepwdCode(dto);
        if(!isTrue){
            return ApiRestResult.err(RetStatusNum.CODE_ERROR);
        }
        SysUserEditPwdDto editDto = new SysUserEditPwdDto("",dto.getNewPwd());
        sysUserService.editPwd(user,editDto);
        return ApiRestResult.ok();
    }
}
